# -*-coding: utf-8 -*-
# by zw on 2017/12/25

import logging

from sanic import response
import hashlib
from utils.mongo import get_user_collection, get_usergroup_collection
from appconfigsvr.auth.permission import permission_check, get_permission, PERMISSION
from sanic import Blueprint

bp = Blueprint('user', url_prefix='/user')
_logger = logging.getLogger(__name__)


@bp.get('/logout')
async def login(request):
    try:
        del request['session']['user']
        del request['session']['permission']
        return response.redirect("/user/login.html")
    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.post('/login')
async def login(request):
    try:
        _json = request.json
        username = _json["username"]
        password = _json["password"]

        _logger.info("username %s", username, password, request.host)
        user = get_user_collection().find_one({"username": username}, )
        if user:
            if validat_token(username, password, user['token']):
                permission = await get_permission(user)
                request['session']['user'] = username
                request['session']['permission'] = permission

                return response.json({"code": 0, "message": "", "data": {}})
        return response.json({"code": 405, "message": "用户名密码错误", "data": {}})
    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.get('/check_user')
async def check_user(request):
    try:
        username = request.raw_args.get("username", "")
        user = get_user_collection().find_one({"username": username})
        if user:
            return response.json({"code": 0, "message": "", "data": {"ok": False}})
        else:
            return response.json({"code": 0, "message": "", "data": {"ok": True}})

    except Exception as e:
        _logger.exception("url %s" % request.url)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.post('/add_user')
async def add_user(request):
    try:
        _json = request.json
        username = _json["username"]
        password = _json["password"]

        token = get_valid_token(username, password)
        user = get_user_collection().find_one({"username": username}, )
        if user:
            return response.json({"code": 4003, "message": "user exist", "data": {}})

        _logger.info("username %s", username, password, request.host)
        get_user_collection().find_one_and_update({"username": username},
                                                        {"$set": {"token": token}},
                                                        upsert=True)
        return response.json({"code": 0, "message": "", "data": {}})
    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.post('/modify_user')
@permission_check
async def modify_user(request):
    try:
        _json = request.json
        username = _json["username"]
        password = _json["password"]
        new_password = _json["new_password"]
        user = get_user_collection().find_one({"username": username}, )
        if user:
            if validat_token(username, password, user['token']):
                token = get_valid_token(username, new_password)
                _logger.info("username %s", username, password, request.host)
                get_user_collection().find_one_and_update({"username": username},
                                                                {"$set": {"token": token}},
                                                                upsert=True)
                return response.json({"code": 0, "message": "", "data": {}})
        return response.json({"code": 1091, "message": "用户名密码错误", "data": {}})
    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.post('/modify_user_admin')
@permission_check(PERMISSION.system)
async def modify_user_admin(request):
    try:
        _json = request.json
        username = _json["username"]
        password = _json["password"]
        group = _json["group"]
        _update = {}
        if group:
            _group = get_usergroup_collection().find_one({"group": group}, {"_id": 0})
            if _group:
                _update.update({"group": group, "groupname": _group['groupname']})

        if password:
            token = get_valid_token(username, password)
            _update.update({"token": token})
        get_user_collection().find_one_and_update({"username": username},
                                                        {"$set": _update},
                                                        upsert=True)
        return response.json({"code": 0, "message": "", "data": {}})
    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


@bp.get('/user_list')
@permission_check(PERMISSION.system)
async def user_list(request):
    try:
        username = request.raw_args.get("username", "")
        page = int(request.raw_args.get("page", 1))
        limit = int(request.raw_args.get("limit", 30))
        cur = get_user_collection().find({"username": {"$regex": username}}, {"_id": 0})
        _count= cur.count()

        cur.skip((page - 1) * limit).limit(limit)
        res = []
        for doc in cur:
            res.append(doc)

        return response.json(
            {"code": 0, "message": "", "data": res, "count": _count})

    except Exception as e:
        _logger.exception(e)
        return response.json({"code": 4003, "message": "error message %s" % e, "data": {}})


def get_valid_token(username, password):
    sign_key = "test!@#"
    m = hashlib.md5()
    m.update("".join([username, password, sign_key]).encode('utf-8'))
    new_token = m.hexdigest()
    return new_token


def validat_token(username, password, token):
    if get_valid_token(username, password) == token:
        return True
    return False
